package com.skp.shaphan;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import javafx.application.Platform;

import javax.swing.JFrame;
import javax.swing.JSplitPane;
import javax.swing.SwingUtilities;

import com.skp.job.ProjectJobException;
import com.skp.shaphan.internalStorage.DBConnector;
import com.skp.shaphan.internalStorage.Fields;
import com.skp.shaphan.internalStorage.Tables;
import com.skp.shaphan.menus.MainMenu;
import com.skp.shaphan.model.ConnectionDetails;
import com.skp.shaphan.savedConnections.SavedConnections;
import com.skp.shaphan.timing.MainTimer;
import com.skp.shaphan.toolbars.MainToolBar;
import com.skp.shaphan.ui.ActionBasedPanel;
import com.skp.shaphan.ui.SQLEditor;
import com.skp.shaphan.ui.connectioncontrols.ConnectionOptions;
import com.skp.shaphan.ui.results.IResultPane;
import com.skp.shaphan.ui.results.JFXResultPane;
import com.skp.shaphan.ui.results.ResultPane;

/**
 * Main application.
 * 
 * The name Shaphan comes from the scribe who read the Bible for King Josiah.  This app
 * will go into the depths of the database and come out with the data you need just
 * as Shaphan did for the king.
 * 
 * And Hilkiah the high priest said unto Shaphan the scribe, I have found the book of 
 * the law in the house of the LORD. And Hilkiah gave the book to Shaphan, and he read it. 
 * II Kings 22:8
 * @author Stephen Phillips
 *
 */
public class ShaphanApp extends JFrame {

	/**
	 * 
	 */
	private static final long serialVersionUID = -1860512130213668706L;
	private static ShaphanApp mainWindow;
	/**
	 * Call to start the application
	 * @param args not used right now
	 */
	public static void main(String[] args) {
		ShaphanApp window = new ShaphanApp();
		window.setVisible(true);
	}
	
	/**
	 * The SQL Editor.  At some point we need to support multiple editors.
	 */
	private SQLEditorsPane sqlEditors;
	private IResultPane resultPane;
	private MainToolBar mainToolBar;
	private Clipboard clipboard;
	private MainTimer mainTimer;
	// Dev Options
	private boolean autoLogin;
	private boolean useJavaFX;
	private int connectionId;
	
	public MainTimer getMainTimer() {
		return mainTimer;
	}

	/**
	 * Creates a new main window for the application.  Creating a new window
	 * will automatically dispose the old one.
	 */
	public ShaphanApp() {
		//  This allows me to open the JavaFX Connection dialog multiple times
		//   https://forums.oracle.com/forums/thread.jspa?messageID=10382744
		Platform.setImplicitExit(false);
		
		// Dev Options
		checkDevOptions();

		if(mainWindow != null) {
			mainWindow.dispose();
		}
		setSize(500, 500);
		ShaphanApp.mainWindow = this;
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setTitle("Project Shaphan");
		clipboard = new Clipboard();
		mainTimer = new MainTimer();
		
		this.setJMenuBar(new MainMenu());
		
		this.setLayout(new BorderLayout());
		mainToolBar = new MainToolBar();
		this.add(mainToolBar, BorderLayout.PAGE_START);
		
		sqlEditors = new SQLEditorsPane();
		if(this.useJavaFX) {
			resultPane = new JFXResultPane();
		} else {
			resultPane = new ResultPane();
		}
		JSplitPane mainArea = new JSplitPane(JSplitPane.VERTICAL_SPLIT, sqlEditors, ((Component)resultPane));
		mainArea.setResizeWeight(0.5);
		//mainArea.setLayout(new GridBagLayout());
		//mainArea.add(sqlEditors, new GridBagConstraints(1, 1, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(5, 5, 5, 5), 5, 5));
		//mainArea.add(resultPane, new GridBagConstraints(1, 2, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(5, 5, 5, 5), 5, 5));
		this.add(mainArea, BorderLayout.CENTER);
		
		//http://java.sun.com/docs/books/tutorial/uiswing/components/rootpane.html
		// Having to use a pane in the Layered pane instead because it causes problems
		//   with the Menubar
		//http://forums.sun.com/thread.jspa?threadID=208887&messageID=1431994&forumID=57
		//new CustomGlassPane(sqlEditors);
		sqlEditors.getUIView().doLayout();
		
		checkforAutoLogin();
	}

	/**
	 * Returns access to the main window.
	 * @return
	 */
	public static ShaphanApp getMainWindow() {
		return ShaphanApp.mainWindow;
	}

	/**
	 * Gets the current sql editor in the window
	 * @return
	 */
	public SQLEditor getSqlEditor() {
		return sqlEditors.getCurrentSQLEditor();
	}
	
	public SQLEditorsPane getSQLEditorsPane() {
		return sqlEditors;
	}
	
	/**
	 * Attaches a connection to the program.  Allows an external program
	 * to launch the program an use a connection already in use by that
	 * program.
	 * @param connection
	 */
	public void attachConnection(Connection connection) {
		ConnectionDetails cd = new ConnectionDetails();
		cd.setConnection(connection);
		sqlEditors.setConnection(cd);
	}
	
	/**
	 * Gets the result pane that displays the results
	 * @return
	 */
	public IResultPane getResultPane() {
		return resultPane;
	}

	public MainToolBar getToolbar() {
		return mainToolBar;
	}

	public Clipboard getClipboard() {
		return clipboard;
	}
	
	public void checkDevOptions() {
		autoLogin = false;
		useJavaFX = false;
		connectionId = 0;
		
		try {
			Connection conn = DBConnector.getInstance().getConnection();
			Statement st = conn.createStatement();
			ResultSet rs = st.executeQuery("select * from " + Tables.Dev);
			if(rs.next()) {
				if(rs.getString(Fields.Dev_Enabled).equals("Y")) {
					if(rs.getString(Fields.Dev_AutoLogin).equals("Y")) {
						autoLogin = true;
						connectionId = rs.getInt(Fields.Dev_AutoConnectionId);
					}
					if(rs.getString(Fields.Dev_UseJavaFX).equals("Y")) {
						useJavaFX = true;
					}
				}
			}
			rs.close();
			st.close();
		} catch (SQLException e) {
			ProjectJobException.displayException(e);
			return;
		}
				
	}
	
	public void checkforAutoLogin() {
		if(autoLogin) {
			SavedConnections sc = SavedConnections.getInstance();
			int index = sc.getIndexForID(connectionId);
			ConnectionOptions options;
			try {
				options = (ConnectionOptions) Class.forName(sc.getConnectionClass(index)).newInstance();
			} catch (InstantiationException e) {
				ProjectJobException.displayException(e);
				return;
			} catch (IllegalAccessException e) {
				ProjectJobException.displayException(e);
				return;
			} catch (ClassNotFoundException e) {
				ProjectJobException.displayException(e);
				return;
			}
			options.setConnectionOptions(sc.getConnectionProperties(index));
			SwingUtilities.invokeLater(((ActionBasedPanel)options).getAction());
		}
	}

	public void setUseJavaFX(boolean useJavaFX) {
		if(useJavaFX != this.useJavaFX) {
			this.useJavaFX = useJavaFX;
			
			Component oldResultPane = (Component)resultPane;
			JSplitPane parent = (JSplitPane)oldResultPane.getParent();
			if(useJavaFX) {
				resultPane = new JFXResultPane();
			} else {
				resultPane = new ResultPane();
			}
			parent.remove(oldResultPane);
			parent.add((Component)resultPane);
		}
	}

}
